package br.ufpe.cin.xmldbdev.dados.xml;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;


/**
 * This is an auxiliary class to write XML files.
 * 
 * @author M2S
 * 
 */
public class XMLFileWriter {
	
	/**
	 * String that represents the extension of the system file.
	 */
	private final String systemExtension = ".system";
	
	/**
	 * The file that will be used by XMLFileWriter to write the file.
	 */
	private File file;
	/**
	 * The document that represents the system.
	 */
	private Document document;

	/**
	 * Constructor.
	 * 
	 * @param filePath -
	 *            the path to the file that will be written
	 */
	public XMLFileWriter(String filePath) {
		this.file = new File(filePath, systemExtension);
	}

	/**
	 * Constructor.
	 * 
	 * @param theFile -
	 *            the file that will be written
	 * @param extension
	 * 	 the name of the file.
	 */
	public XMLFileWriter(File theFile, String extension) {
		this.file = new File(theFile, extension);
	}

	/**
	 * Constructor.
	 * 
	 * @param rootElementName -
	 *            the root element of the xml document
	 * @param filePath -
	 *            the path to the file that will be written
	 */
	public XMLFileWriter(String rootElementName, String filePath) {
		this.file = new File(filePath, systemExtension);
		this.createDocument(rootElementName);
	}

	/**
	 * Constructor.
	 * 
	 * @param rootElementName -
	 *            the root element of the xml document
	 * @param theFile -
	 *            the file that will be written
	 */
	public XMLFileWriter(String rootElementName, File theFile) {
		this.file = new File(theFile, systemExtension);
		this.createDocument(rootElementName);
	}
	/**
	 * the constructor. 
	 * @param rootElementName
	 * 	the root element.
	 * @param theFile
	 * 	the file.
	 * @param fileExtension
	 *  the name of the file.
	 */
	public XMLFileWriter(String rootElementName, File theFile, 
			String fileExtension) {
		this.file = new File(theFile, fileExtension);
		this.createDocument(rootElementName);
	}

	/**
	 * This method should be called after all other methods. It doesn't need to
	 * be called if the rootElementName has been specified in the constructor.
	 * 
	 * @param rootElementName -
	 *            the root element of the xml document
	 */
	public void createDocument(String rootElementName) {
		//SET HERE THE REFERENCE TO THE XML SCHEMA
		this.document = new Document();
		Element root = new Element(rootElementName);
		this.document.setRootElement(root);
	}

	/**
	 * Method that adds a node to the XML Document.
	 * 
	 * @param elementName -
	 *            the name of the element to be added
	 * @param elementValue -
	 *            the value of the element to be added
	 * @throws SystemException -
	 *             thrown if the document has not been created prior to this
	 *             method invocation
	 */
	@SuppressWarnings("unchecked")
	public void addNode(String elementName, String elementValue)
			throws Exception {
		if (this.document != null) {
			Element element = new Element(elementName);
			element.setText(elementValue);
			this.document.
				getRootElement().getChildren().add(element);
		} else {
			throw new Exception("Don't try to add a node to a document"
					+ " that has not been created yet.");
		}
	}
	/**
	 * Add a complex node.
	 * @param element
	 * 	the element.
	 * @throws SystemException
	 * 	if the document is null.
	 */
	public void addComplexNode(Element element) throws Exception {
		if (this.document != null) {
			this.document.getRootElement().addContent(element);
		} else {
			throw new Exception("Don't try to add a node to a document"
				+ " that has not been created yet.");
		}	
	}


	/**
	 * This method effectively writes the xml file in the directory.
	 * 
	 * @throws SystemException -
	 *             thrown if the document has not been created prior to this
	 *             method invocation
	 * @throws IOException -
	 *             thrown if the file could not be written, for example, if the
	 *             directory is 'Read-Only'
	 */
	public void writeFile() throws Exception, IOException {
		if (this.document != null) {
			XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
			FileWriter fw = new FileWriter(file);
			outputter.output(this.document, fw);
			fw.close();
		} else {
			throw new Exception("The file could not be written once the "
					+ "document has not been created yet.");
		}
	}

}
